package com.xhd.db;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;

import com.xhd.base.log.Log;
import com.xhd.base.log.LogFactory;
import com.xhd.exception.DatabaseException;
import com.xhd.server.EventObject;
import com.xhd.server.ServerConfig;
import com.xhd.xml.XMLSerializer;

public class XDBManager {
	 private static XDBManager XDBManagerIns;
	  private static int jm385 = 0;
	  private HashMap jm386 = new HashMap(8);
	  private HashMap jm387 = new HashMap(8);
	  private HashMap jm388 = new HashMap(8);
	  private int jm389 = 0;
	  private HashMap jm390 = new HashMap(8);
	  private boolean jm391 = false;
	  private static final Log jm9;
	  private DaoMonitor jm54;
	  static Class clasins;

	  static
	  {
	    Class temp_calss = clasins;
	    if (temp_calss == null)
	    {
	      try
	      {
	         XDBManagerIns.clasins = Class.forName("com.sinocc.systemdbmanager.CPCDBManager");
	      }
	      catch (ClassNotFoundException localClassNotFoundException)
	      {
	        throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
	      }
	    }
	    jm9 = LogFactory.getLog(temp_calss);
	  }

	  private XDBManager()
	    throws DatabaseException
	  {
	    jm124();
	    this.jm54 = DaoMonitor.getInstance();
	  }

	  public static XDBManager getInstance()
	    throws DatabaseException
	  {
	    if (XDBManagerIns == null)
	    {
	      XDBManagerIns = new XDBManager();
	      XDBManagerIns.jm384();
	    }
	    return XDBManagerIns;
	  }

	  public static synchronized int getTemporaryTableId()
	  {
	    if (jm385++ > 99999)
	      jm385 = 1;
	    return jm385;
	  }

	  public Vector getUseInfo()
	  {
	    Vector localVector = new Vector();
	    HashMap localHashMap = null;
	    if (this.jm387.size() > 0)
	    {
	      Iterator localIterator = this.jm387.values().iterator();
	      while (localIterator.hasNext())
	      {
	        DBPool localDBPool = (DBPool)localIterator.next();
	        localHashMap = new HashMap();
	        localHashMap.put("id", localDBPool.getId());
	        localHashMap.put("max", String.valueOf(localDBPool.getPoolSize()));
	        localHashMap.put("use", String.valueOf(localDBPool.getUseSize()));
	        localHashMap.put("free", String.valueOf(localDBPool.getIdleSize()));
	        localHashMap.put("idle", String.valueOf(localDBPool.getIdleSize()));
	        localHashMap.put("oid", localDBPool.toString());
	        localVector.add(localHashMap);
	      }
	    }
	    localHashMap = new HashMap();
	    localHashMap.put("id", "No Pool");
	    localHashMap.put("max", "0");
	    localHashMap.put("use", String.valueOf(this.jm389));
	    localHashMap.put("free", "0");
	    localHashMap.put("idle", "0");
	    localHashMap.put("oid", super.toString());
	    localVector.add(localHashMap);
	    return localVector;
	  }

	  private synchronized void jm124()
	    throws DatabaseException
	  {
	    ServerConfig.Event.onEvent(EventObject.TIME_BEFORE | EventObject.EVENT_DBPOOL_INIT, this);
	    vaultcheck();
	    jm383();
	    ServerConfig.Event.onEvent(EventObject.TIME_AFTER | EventObject.EVENT_DBPOOL_INIT, this);
	  }

	  private void vaultcheck()
	    throws DatabaseException
	  {
	    if (ServerConfig.Vaults == null)
	      throw new DatabaseException(30045);
	    try
	    {
	      for (int i = 0; i < ServerConfig.Vaults.size(); ++i)
	      {
	        DBConfig localDBConfig = new DBConfig();
	        Map localMap = (Map)ServerConfig.Vaults.get(i);
	        if (localDBConfig.loadFromVault(localMap))
	        {
	          DBConfig.refreshConfig(localDBConfig);
	          Driver localDriver = null;
	          if (localDBConfig.getPoolType() == 1)
	          {
	            localDriver = (Driver)this.jm386.get(localDBConfig.getDriverName());
	            if (localDriver == null)
	            {
	              localDriver = (Driver)Class.forName(localDBConfig.getDriverName()).newInstance();
	              DriverManager.registerDriver(localDriver);
	              this.jm386.put(localDBConfig.getDriverName(), localDriver);
	            }
	          }
	          Object localObject = null;
	          if (localDBConfig.getPoolType() == 1)
	          {
	            localObject = new XDBPool(localDBConfig);
	          }
	          else
	          {
	            if (localDBConfig.getPoolType() != 2)
	              continue;
	            localObject = new ExtDBPool(localDBConfig);
	           
	            continue;
	          }
	          label167: ((DBPool)localObject).setDriver(localDriver);
	          this.jm387.put(localDBConfig.getId(), localObject);
	          jm9.trace("Create database pool: " + localDBConfig.getId() + "(" + localObject.toString() + ")");
	        }
	        else
	        {
	          jm9.error("Error: Invaild vault " + localMap.toString());
	        }
	      }
	    }
	    catch (Throwable localThrowable)
	    {
	      jm9.error(localThrowable);
	      throw new DatabaseException(30011);
	    }
	  }

	  public synchronized void release()
	  {
	    try
	    {
	      Object localObject;
	      if ((this.jm387 != null) && (this.jm387.size() > 0))
	      {
	    	Iterator  localIterator = this.jm387.values().iterator();
	        while ((localIterator != null) && (localIterator.hasNext()))
	        {
	          localObject = (DBPool)localIterator.next();
	          if (localObject != null)
	            ((DBPool)localObject).freeAllConn();
	          localObject = null;
	        }
	        this.jm387.clear();
	        this.jm387 = null;
	      }
	      if ((this.jm386 == null) || (this.jm386.size() <= 0))
	        return;
	      Iterator localIterator = this.jm386.values().iterator();
	      while ((localIterator != null) && (localIterator.hasNext()))
	      {
	        localObject = (Driver)localIterator.next();
	        try
	        {
	          if (localObject != null)
	            DriverManager.deregisterDriver((Driver)localObject);
	        }
	        catch (SQLException localSQLException)
	        {
	        }
	      }
	      this.jm386.clear();
	      this.jm386 = null;
	    }
	    catch (Exception localException)
	    {
	      localException.printStackTrace();
	    }
	  }

	  public void freeAllConn(String paramString)
	  {
	    if (paramString == null)
	      return;
	    DBPool localDBPool = (DBPool)this.jm387.get(paramString);
	    if (localDBPool == null)
	      return;
	    localDBPool.freeAllConn();
	    localDBPool = null;
	  }

	  public boolean refreshConfig(DBConfig paramDBConfig)
	  {
	    if (paramDBConfig == null)
	      return false;
	    DBPool localDBPool = (DBPool)this.jm387.get(paramDBConfig.getId());
	    if (localDBPool != null)
	    {
	      localDBPool.setConfig(paramDBConfig);
	      localDBPool.freeAllConn();
	      DBConfig.refreshConfig(paramDBConfig);
	      return true;
	    }
	    return false;
	  }

	  public DBPool getPool(DBConfig paramDBConfig)
	  {
	    if ((paramDBConfig == null) || (paramDBConfig.getId() == null) || (this.jm387 == null))
	      return null;
	    Object localObject = (DBPool)this.jm387.get(paramDBConfig.getId());
	    if (localObject == null)
	    {
	      if (paramDBConfig.getPoolType() == 1)
	      {
	        localObject = new XDBPool(paramDBConfig);
	        this.jm387.put(paramDBConfig.getId(), localObject);
	      }
	      else if (paramDBConfig.getPoolType() == 2)
	      {
	        localObject = new ExtDBPool(paramDBConfig);
	        this.jm387.put(paramDBConfig.getId(), localObject);
	      }
	      else
	      {
	        return (DBPool) localObject;
	      }
	      jm9.trace("Create database pool: " + paramDBConfig.getId() + "(" + localObject.toString() + ")");
	    }
	    return ((DBPool)localObject);
	  }

	  private void jm383()
	    throws DatabaseException
	  {
	    FileInputStream localFileInputStream;
	    try
	    {
	      localFileInputStream = new FileInputStream(new File(ServerConfig.getConfFilePath("rptdb")));
	    }
	    catch (IOException localIOException)
	    {
	      throw new DatabaseException(10030);
	    }
	    Vector localVector = null;
	    try
	    {
	      XMLSerializer localXMLSerializer = new XMLSerializer(localFileInputStream, false);
	      localVector = localXMLSerializer.getCollection("rptdb-type");
	      localFileInputStream.close();
	    }
	    catch (Exception localException1)
	    {
	      throw new DatabaseException(10031);
	    }
	    if ((localVector == null) || (localVector.size() == 0))
	      return;
	    for (int i = 0; i < localVector.size(); ++i)
	    {
	      Map localMap = (Map)localVector.get(i);
	      String str1 = (String)localMap.get("db-type");
	      String str2 = (String)localMap.get("db-driver");
	      String str3 = (String)localMap.get("max-connections");
	      String str4 = (String)localMap.get("delay");
	      HashMap localHashMap = new HashMap(8);
	      localHashMap.put("macconn", str3);
	      localHashMap.put("delay", str4);
	      this.jm388.put(str1, localHashMap);
	      String str5 = (String)localMap.get("set-tran-level");
	      if ((str5 != null) && ("true".equals(str5)))
	      {
	        str5 = (String)localMap.get("select-tran-level");
	        if ((str5 != null) && (str5.length() > 0))
	          localHashMap.put("select-tran-level", str5);
	        str5 = (String)localMap.get("update-tran-level");
	        if ((str5 != null) && (str5.length() > 0))
	          localHashMap.put("update-tran-level", str5);
	      }
	      try
	      {
	        if (!(this.jm386.containsKey(str2)))
	        {
	          Driver localDriver = (Driver)Class.forName(str2).newInstance();
	          DriverManager.registerDriver(localDriver);
	          this.jm386.put(str2, localDriver);
	        }
	      }
	      catch (Exception localException2)
	      {
	        jm9.warn("Load reprot driver " + str2, localException2);
	      }
	    }
	  }

	  protected DBConn getNoPoolConnection(DBConfig paramDBConfig)
	    throws DatabaseException
	  {
	    Properties localProperties = new Properties();
	    localProperties.put("user", paramDBConfig.getUser());
	    localProperties.put("password", paramDBConfig.getPassword());
	    try
	    {
	      String str = paramDBConfig.getURL();
	      Driver localDriver = (Driver)this.jm390.get(str);
	      if (localDriver == null)
	      {
	        localDriver = DriverManager.getDriver(str);
	        this.jm390.put(str, localDriver);
	      }
	      Connection localConnection = localDriver.connect(str, localProperties);
	      DBConn localDBConn = null;
	      if (localConnection != null)
	      {
	        this.jm389 += 1;
	        localDBConn = new DBConn(null, localConnection, paramDBConfig);
	        localDBConn.setCheckConn(paramDBConfig.isCheckConn());
	        this.jm54.counterAdd();
	      }
	      return localDBConn;
	    }
	    catch (SQLException localSQLException)
	    {
	      jm9.error(localSQLException);
	      throw new DatabaseException(30072, paramDBConfig.getURL(), localSQLException.getMessage());
	    }
	  }

	  protected void freeNoPoolConnection(DBConn paramDBConn)
	  {
	    if (paramDBConn == null)
	      return;
	    paramDBConn.release();
	    this.jm389 -= 1;
	    this.jm54.counterSub();
	  }

	  private synchronized void jm384()
	  {
	    if ((!(ServerConfig.UseDBArea)) || (this.jm391))
	      return;
	    this.jm391 = true;
	    for (int i = 0; i < ServerConfig.Vaults.size(); ++i)
	    {
	      DBConfig localDBConfig = new DBConfig();
	      if (!(localDBConfig.loadFromVault((Map)ServerConfig.Vaults.get(i))))
	        continue;
	      XDBArea.initArea(localDBConfig);
	    }
	  }

	
}
